﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.IO;

namespace YArchitech.Controls.ImgListView
{
	public class ImageListViewItem
	{
		[Category("Appearance")]
		[Browsable(true)]
		[Description("Gets or sets the background color of the item.")]
		[DefaultValue(typeof(System.Drawing.Color), "Transparent")]
		public System.Drawing.Color BackColor
		{
			get
			{
				return this.mBackColor;
			}
			set
			{
				if (value != this.mBackColor)
				{
					this.mBackColor = value;
					if (this.mImageListView != null)
					{
						this.mImageListView.Refresh();
					}
				}
			}
		}

		[Category("Behavior")]
		[Browsable(false)]
		[Description("Gets the cache state of the item thumbnail.")]
		public CacheState ThumbnailCacheState
		{
			get
			{
				return this.mImageListView.cacheManager.GetCacheState(this.mGuid);
			}
		}

		[Category("Appearance")]
		[Browsable(false)]
		[Description("Gets a value determining if the item is focused.")]
		public bool Focused
		{
			get
			{
				return this.owner != null && this.owner.FocusedItem != null && this == this.owner.FocusedItem;
			}
			set
			{
				if (this.owner != null)
				{
					this.owner.FocusedItem = this;
				}
			}
		}

		[Category("Appearance")]
		[Browsable(true)]
		[Description("Gets or sets the foreground color of the item.")]
		[DefaultValue(typeof(System.Drawing.Color), "WindowText")]
		public System.Drawing.Color ForeColor
		{
			get
			{
				return this.mForeColor;
			}
			set
			{
				if (value != this.mForeColor)
				{
					this.mForeColor = value;
					if (this.mImageListView != null)
					{
						this.mImageListView.Refresh();
					}
				}
			}
		}

		[Category("Behavior")]
		[Browsable(false)]
		[Description("Gets the unique identifier for this item.")]
		internal Guid Guid
		{
			get
			{
				return this.mGuid;
			}
			private set
			{
				this.mGuid = value;
			}
		}

		[Category("Behavior")]
		[Browsable(false)]
		[Description("Gets the virtual item key associated with this item.")]
		public object VirtualItemKey
		{
			get
			{
				return this.mVirtualItemKey;
			}
		}

		[Category("Behavior")]
		[Browsable(false)]
		[Description("Gets the ImageListView owning this item.")]
		public ImageListView ImageListView
		{
			get
			{
				return this.mImageListView;
			}
			private set
			{
				this.mImageListView = value;
			}
		}

		[Category("Behavior")]
		[Browsable(false)]
		[Description("Gets the index of the item.")]
		[EditorBrowsable(EditorBrowsableState.Advanced)]
		public int Index
		{
			get
			{
				return this.mIndex;
			}
		}

		[Category("Appearance")]
		[Browsable(true)]
		[Description("Gets or sets a value determining if the item is selected.")]
		[DefaultValue(false)]
		public bool Selected
		{
			get
			{
				return this.mSelected;
			}
			set
			{
				if (value != this.mSelected)
				{
					this.mSelected = value;
					if (this.mImageListView != null)
					{
						this.mImageListView.OnSelectionChangedInternal();
					}
				}
			}
		}

		[Category("Data")]
		[Browsable(true)]
		[Description("Gets or sets the user-defined data associated with the item.")]
		public object Tag { get; set; }

		[Category("Appearance")]
		[Browsable(true)]
		[Description("Gets or sets the text associated with this item. If left blank, item Text reverts to the name of the image file.")]
		public string Text
		{
			get
			{
				return this.mText;
			}
			set
			{
				this.mText = value;
				if (this.mImageListView != null)
				{
					this.mImageListView.Refresh();
				}
			}
		}

		[Category("Appearance")]
		[Browsable(false)]
		[Description("Gets the thumbnail image.")]
		public Image ThumbnailImage
		{
			get
			{
				if (this.mImageListView == null)
				{
					throw new Autodesk.Revit.Exceptions.InvalidOperationException("Owner control is null.");
				}
				if (this.ThumbnailCacheState == CacheState.Error)
				{
					return this.mImageListView.ErrorImage;
				}
				Image image = this.mImageListView.cacheManager.GetImage(this.Guid);
				if (image != null)
				{
					return image;
				}
				if (this.isVirtualItem)
				{
					this.mImageListView.cacheManager.Add(this.Guid, this.mVirtualItemKey, this.mImageListView.ThumbnailSize, this.mImageListView.UseEmbeddedThumbnails);
				}
				else
				{
					this.mImageListView.cacheManager.Add(this.Guid, this.FileName, this.mImageListView.ThumbnailSize, this.mImageListView.UseEmbeddedThumbnails);
				}
				return this.mImageListView.DefaultImage;
			}
		}

		[Category("Appearance")]
		[Browsable(true)]
		[Description("Gets or sets the draw order of the item.")]
		[DefaultValue(0)]
		public int ZOrder
		{
			get
			{
				return this.mZOrder;
			}
			set
			{
				this.mZOrder = value;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the last access date of the image file represented by this item.")]
		public DateTime DateAccessed
		{
			get
			{
				this.UpdateFileInfo();
				return this.mDateAccessed;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the creation date of the image file represented by this item.")]
		public DateTime DateCreated
		{
			get
			{
				this.UpdateFileInfo();
				return this.mDateCreated;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the modification date of the image file represented by this item.")]
		public DateTime DateModified
		{
			get
			{
				this.UpdateFileInfo();
				return this.mDateModified;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the shell type of the image file represented by this item.")]
		public string FileType
		{
			get
			{
				this.UpdateFileInfo();
				return this.mFileType;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets or sets the name of the image fie represented by this item.")]
		public string FileName
		{
			get
			{
				return this.mFileName;
			}
			set
			{
				if (this.mFileName != value)
				{
					this.mFileName = value;
					if (!this.isVirtualItem)
					{
						this.isDirty = true;
						if (this.mImageListView != null)
						{
							this.mImageListView.cacheManager.Remove(this.Guid);
							this.mImageListView.itemCacheManager.Add(this);
							this.mImageListView.Refresh();
						}
					}
				}
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the path of the image fie represented by this item.")]
		public string FilePath
		{
			get
			{
				this.UpdateFileInfo();
				return this.mFilePath;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets file size in bytes.")]
		public long FileSize
		{
			get
			{
				this.UpdateFileInfo();
				return this.mFileSize;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets image dimensions.")]
		public Size Dimensions
		{
			get
			{
				this.UpdateFileInfo();
				return this.mDimensions;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets image resolution in pixels per inch.")]
		public SizeF Resolution
		{
			get
			{
				this.UpdateFileInfo();
				return this.mResolution;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets image deascription.")]
		public string ImageDescription
		{
			get
			{
				this.UpdateFileInfo();
				return this.mImageDescription;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the camera model.")]
		public string EquipmentModel
		{
			get
			{
				this.UpdateFileInfo();
				return this.mEquipmentModel;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the date and time the image was taken.")]
		public DateTime DateTaken
		{
			get
			{
				this.UpdateFileInfo();
				return this.mDateTaken;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the name of the artist.")]
		public string Artist
		{
			get
			{
				this.UpdateFileInfo();
				return this.mArtist;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets image copyright information.")]
		public string Copyright
		{
			get
			{
				this.UpdateFileInfo();
				return this.mCopyright;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the exposure time in seconds.")]
		public string ExposureTime
		{
			get
			{
				this.UpdateFileInfo();
				return this.mExposureTime;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the F number.")]
		public float FNumber
		{
			get
			{
				this.UpdateFileInfo();
				return this.mFNumber;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the ISO speed.")]
		public ushort ISOSpeed
		{
			get
			{
				this.UpdateFileInfo();
				return this.mISOSpeed;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the shutter speed.")]
		public string ShutterSpeed
		{
			get
			{
				this.UpdateFileInfo();
				return this.mShutterSpeed;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets the lens aperture value.")]
		public string Aperture
		{
			get
			{
				this.UpdateFileInfo();
				return this.mAperture;
			}
		}

		[Category("Data")]
		[Browsable(false)]
		[Description("Gets user comments.")]
		public string UserComment
		{
			get
			{
				this.UpdateFileInfo();
				return this.mUserComment;
			}
		}

		public ImageListViewItem()
		{
			this.mIndex = -1;
			this.owner = null;
			this.mBackColor = System.Drawing.Color.Transparent;
			this.mForeColor = SystemColors.WindowText;
			this.mZOrder = 0;
			this.Guid = Guid.NewGuid();
			this.ImageListView = null;
			this.Selected = false;
			this.isDirty = true;
			this.editing = false;
			this.mVirtualItemKey = null;
			this.isVirtualItem = false;
		}

		public ImageListViewItem(string filename) : this()
		{
			this.mFileName = filename;
			this.mText = Path.GetFileNameWithoutExtension(filename);
		}

		public ImageListViewItem(object key, string text, Size dimensions) : this()
		{
			this.isVirtualItem = true;
			this.mVirtualItemKey = key;
			this.mText = text;
			this.mDimensions = dimensions;
		}

		public ImageListViewItem(object key, string text) : this(key, text, Size.Empty)
		{
		}

		public ImageListViewItem(object key) : this(key, string.Empty, Size.Empty)
		{
		}

		public Image GetImage()
		{
			if (!this.editing)
			{
				this.BeginEdit();
			}
			Image result;
			if (this.isVirtualItem)
			{
				VirtualItemImageEventArgs virtualItemImageEventArgs = new VirtualItemImageEventArgs(this.mVirtualItemKey);
				this.mImageListView.RetrieveVirtualItemImageInternal(virtualItemImageEventArgs);
				result = Image.FromFile(virtualItemImageEventArgs.FileName);
			}
			else
			{
				result = Image.FromFile(this.mFileName);
			}
			if (!this.editing)
			{
				this.EndEdit();
			}
			return result;
		}

		public void BeginEdit()
		{
			if (this.editing)
			{
				throw new Autodesk.Revit.Exceptions.InvalidOperationException("Already editing this item.");
			}
			if (this.mImageListView == null)
			{
				throw new Autodesk.Revit.Exceptions.InvalidOperationException("Owner control is null.");
			}
			this.UpdateFileInfo();
			this.mImageListView.cacheManager.BeginItemEdit(this.mGuid, this.mFileName);
			this.mImageListView.itemCacheManager.BeginItemEdit(this.mGuid);
			this.editing = true;
		}

		public void EndEdit(bool update)
		{
			if (!this.editing)
			{
				throw new Autodesk.Revit.Exceptions.InvalidOperationException("This item is not being edited.");
			}
			if (this.mImageListView == null)
			{
				throw new Autodesk.Revit.Exceptions.InvalidOperationException("Owner control is null.");
			}
			this.mImageListView.cacheManager.EndItemEdit(this.mGuid);
			this.mImageListView.itemCacheManager.EndItemEdit(this.mGuid);
			this.editing = false;
			if (update)
			{
				this.Update();
			}
		}

		public void EndEdit()
		{
			this.EndEdit(true);
		}

		public void Update()
		{
			this.isDirty = true;
			if (this.mImageListView != null)
			{
				this.mImageListView.cacheManager.Remove(this.mGuid, true);
				this.mImageListView.itemCacheManager.Add(this);
				this.mImageListView.Refresh();
			}
		}

		public string GetSubItemText(ColumnType type)
		{
			switch (type)
			{
			case ColumnType.Name:
				return this.Text;
			case ColumnType.DateAccessed:
				if (this.DateAccessed == DateTime.MinValue)
				{
					return "";
				}
				return this.DateAccessed.ToString("g");
			case ColumnType.DateCreated:
				if (this.DateCreated == DateTime.MinValue)
				{
					return "";
				}
				return this.DateCreated.ToString("g");
			case ColumnType.DateModified:
				if (this.DateModified == DateTime.MinValue)
				{
					return "";
				}
				return this.DateModified.ToString("g");
			case ColumnType.FileType:
				return this.FileType;
			case ColumnType.FileName:
				return this.FileName;
			case ColumnType.FilePath:
				return this.FilePath;
			case ColumnType.FileSize:
				if (this.FileSize == 0L)
				{
					return "";
				}
				return Utility.FormatSize(this.FileSize);
			case ColumnType.Dimensions:
				if (this.Dimensions == Size.Empty)
				{
					return "";
				}
				return string.Format("{0} x {1}", this.Dimensions.Width, this.Dimensions.Height);
			case ColumnType.Resolution:
				if (this.Resolution == SizeF.Empty)
				{
					return "";
				}
				return string.Format("{0} x {1}", this.Resolution.Width, this.Resolution.Height);
			case ColumnType.ImageDescription:
				return this.ImageDescription;
			case ColumnType.EquipmentModel:
				return this.EquipmentModel;
			case ColumnType.DateTaken:
				if (this.DateTaken == DateTime.MinValue)
				{
					return "";
				}
				return this.DateTaken.ToString("g");
			case ColumnType.Artist:
				return this.Artist;
			case ColumnType.Copyright:
				return this.Copyright;
			case ColumnType.ExposureTime:
				return this.ExposureTime;
			case ColumnType.FNumber:
				if (this.FNumber == 0f)
				{
					return "";
				}
				return this.FNumber.ToString("f2");
			case ColumnType.ISOSpeed:
				if (this.ISOSpeed == 0)
				{
					return "";
				}
				return this.ISOSpeed.ToString();
			case ColumnType.ShutterSpeed:
				return this.ShutterSpeed;
			case ColumnType.Aperture:
				return this.Aperture;
			case ColumnType.UserComment:
				return this.UserComment;
			default:
				throw new ArgumentException("Unknown column type", "type");
			}
		}

		private void UpdateFileInfo()
		{
			if (!this.isDirty)
			{
				return;
			}
			if (this.isVirtualItem)
			{
				if (this.mImageListView != null)
				{
					VirtualItemDetailsEventArgs virtualItemDetailsEventArgs = new VirtualItemDetailsEventArgs(this.mVirtualItemKey);
					this.mImageListView.RetrieveVirtualItemDetailsInternal(virtualItemDetailsEventArgs);
					this.UpdateDetailsInternal(virtualItemDetailsEventArgs);
				}
			}
			else
			{
				Utility.ShellImageFileInfo info = new Utility.ShellImageFileInfo(this.mFileName);
				this.UpdateDetailsInternal(info);
			}
			this.isDirty = false;
		}

		internal void UpdateDetailsInternal(Utility.ShellImageFileInfo info)
		{
			if (!this.isDirty)
			{
				return;
			}
			this.mDateAccessed = info.LastAccessTime;
			this.mDateCreated = info.CreationTime;
			this.mDateModified = info.LastWriteTime;
			this.mFileSize = info.Size;
			this.mFileType = info.TypeName;
			this.mFilePath = info.DirectoryName;
			this.mDimensions = info.Dimensions;
			this.mResolution = info.Resolution;
			this.mImageDescription = info.ImageDescription;
			this.mEquipmentModel = info.EquipmentModel;
			this.mDateTaken = info.DateTaken;
			this.mArtist = info.Artist;
			this.mCopyright = info.Copyright;
			this.mExposureTime = info.ExposureTime;
			this.mFNumber = info.FNumber;
			this.mISOSpeed = info.ISOSpeed;
			this.mShutterSpeed = info.ShutterSpeed;
			this.mAperture = info.ApertureValue;
			this.mUserComment = info.UserComment;
			this.isDirty = false;
		}

		internal void UpdateDetailsInternal(VirtualItemDetailsEventArgs info)
		{
			if (!this.isDirty)
			{
				return;
			}
			this.mDateAccessed = info.DateAccessed;
			this.mDateCreated = info.DateCreated;
			this.mDateModified = info.DateModified;
			this.mFileName = info.FileName;
			this.mFileSize = info.FileSize;
			this.mFileType = info.FileType;
			this.mFilePath = info.FilePath;
			this.mDimensions = info.Dimensions;
			this.mResolution = info.Resolution;
			this.mImageDescription = info.ImageDescription;
			this.mEquipmentModel = info.EquipmentModel;
			this.mDateTaken = info.DateTaken;
			this.mArtist = info.Artist;
			this.mCopyright = info.Copyright;
			this.mExposureTime = info.ExposureTime;
			this.mFNumber = info.FNumber;
			this.mISOSpeed = info.ISOSpeed;
			this.mShutterSpeed = info.ShutterSpeed;
			this.mAperture = info.Aperture;
			this.mUserComment = info.UserComment;
			this.isDirty = false;
		}

		internal int mIndex;

		private System.Drawing.Color mBackColor;

		private System.Drawing.Color mForeColor;

		private Guid mGuid;

		internal ImageListView mImageListView;

		internal bool mSelected;

		private string mText;

		private int mZOrder;

		private DateTime mDateAccessed;

		private DateTime mDateCreated;

		private DateTime mDateModified;

		private string mFileType;

		private string mFileName;

		private string mFilePath;

		private long mFileSize;

		private Size mDimensions;

		private SizeF mResolution;

		private string mImageDescription;

		private string mEquipmentModel;

		private DateTime mDateTaken;

		private string mArtist;

		private string mCopyright;

		private string mExposureTime;

		private float mFNumber;

		private ushort mISOSpeed;

		private string mShutterSpeed;

		private string mAperture;

		private string mUserComment;

		internal bool isVirtualItem;

		internal object mVirtualItemKey;

		internal ImageListView.ImageListViewItemCollection owner;

		internal bool isDirty;

		private bool editing;
	}
}
